﻿using Blm.Utils.Extensions;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Options;
using System;
using System.IO;
using System.Threading.Tasks;
using VisionCloud.Core.Model.Ms;
using VisionCloud.Domain.Common;
using VisionCloud.Domain.DtoModel.Ms;
using VisionCloud.Domain.Repository.Interface.Ms;
using VisionCloud.Domain.UnitOfWork;
using VisionCloud.Utility.Option;
using VisionCloud.Utility;

namespace VisionCloud.Service.Ms
{
    public class MsUpdateService
    {
        public IMsUpdateRepository MsUpdateRepository { get; set; }
        public IUnitOfWork UnitOfWork { get; set; }
        private UploadFileOptions _uploadFileOptions;

        public MsUpdateService(IOptionsMonitor<UploadFileOptions> option)
        {
            if (option.IsNull())
                throw new ArgumentNullException($"{typeof(UploadFileOptions)} was null");
            _uploadFileOptions = option.CurrentValue;
        }

        public async Task<ApiResult> UploadFile(string version, IFormFile formFile)
        {
            int _version = 0;
            if (!int.TryParse(version, out _version))
            {
                return new ApiResult(AjaxCode.Error, "YB0073".SLocalize());
            }
            using (var stream = formFile.OpenReadStream())
            {
                if (stream.Length == 0)
                    return new ApiResult(AjaxCode.Error, "YB0007".SLocalize());

                //var randomPath = Guid.NewGuid().ToShortGuid();
                var path = Path.Combine(_uploadFileOptions.ParentDir, _uploadFileOptions.UpdateDir, version);
                if (!Directory.Exists(path)) Directory.CreateDirectory(path);
                using (var fileStream = new FileStream(Path.Combine(path, formFile.FileName), FileMode.Create))
                {
                    await formFile.CopyToAsync(fileStream);
                }
                if (MsUpdateRepository.Any(o => o.Version == _version))
                {
                    MsUpdateRepository.Update(o => o.Version == _version, (Action<MsUpdate>)(d =>
                    {
                        d.FilePath = path;
                        d.LastUpdatedBy = OperatorProvider.Get().YunUserGuid;
                        d.LastUpdatedDate = DateTime.Now;
                        d.FileName = formFile.FileName;
                    }));
                }
                else
                {
                    var entity = new MsUpdate()
                    {
                        UpdateId = Guid.NewGuid(),
                        FilePath = path,
                        Version = _version,
                        FileName = formFile.FileName,
                        CreatedBy = OperatorProvider.Get().YunUserGuid,
                        CreatedDate = DateTime.Now,
                        LastUpdatedBy = OperatorProvider.Get().YunUserGuid,
                        LastUpdatedDate = DateTime.Now
                    };
                    MsUpdateRepository.Add(entity);
                }
                await UnitOfWork.SaveChangesAsync();

                return ApiResult.Success();
            }
        }

        public async Task<MsUpdateDto> GetLastUpdate()
        {
            var record = await MsUpdateRepository.GetLastUpdate();
            return record;
        }

        public async Task<(Stream fileStream, string fileName, string fileExt)> DownloadSingle(Guid key)
        {
            return await Task.Run(() =>
            {
                var entity = MsUpdateRepository.GetById(key);
                if (entity.IsNotNull())
                {
                    var filePath = Path.Combine(entity.FilePath, entity.FileName);
                    if (!File.Exists(filePath))
                        throw new OperationException("GX00007".SLocalize());
                    var stream = File.OpenRead(filePath);
                    string fileExt = Path.GetExtension(entity.FileName);
                    return (stream, entity.FileName, fileExt);
                }
                else
                    throw new OperationException("YB0072".SLocalize());
            });
        }
    }
}